package com.hf.wujian.model.imp;

import com.hf.wujian.constant.ModelConstant;
import com.hf.wujian.exception.ChannelException;
import com.hf.wujian.exception.CreateRoomException;
import com.hf.wujian.exception.NoRoomException;
import com.hf.wujian.model.GameHall;
import com.hf.wujian.model.GameRole;
import com.hf.wujian.model.GameRoom;
import com.hf.wujian.model.GameUser;
import io.netty.channel.ChannelHandlerContext;
import java.io.Serializable;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * 游戏用户实现类
 *
 * @author hf
 * @date 2018/11/23
 * @version 1.0
 *
 */
public class BSHGameUser implements GameUser,Serializable {

    /**
     * 昵称
     */
    private String nickName;
    /**
     * 唯一标志符
     */
    private String uuid;
    /**
     * 游戏角色
     */
    private GameRole gameRole;
    /**
     * 所属房间
     */
    private GameRoom gameRoom;
    /**
     * 所属大厅
     */
    private GameHall gameHall;
    /**
     * 客户端通道
     */
    private ChannelHandlerContext ctx;
    /**
     * 游戏状态
     * ps:初始化为未准备
     */
    private int playStatus = ModelConstant.USER_UNPREPARED;

    private ReadWriteLock userRwlock = new ReentrantReadWriteLock(true);//用户读写锁

    public BSHGameUser(String nickName,String uuid,ChannelHandlerContext ctx,GameHall gameHall){
        this.nickName = nickName;
        //生成唯一标识符
        this.uuid = uuid;
        this.ctx = ctx;
        this.gameHall = gameHall;
    }

    /**
     * 当两个用户的uuid相等时返回true
     * @param obj 另一个用户
     * @return 对比结果
     */
    @Override
    public boolean equals(Object obj) {
        if (obj instanceof BSHGameUser){
            BSHGameUser gameUser = (BSHGameUser) obj;
            if(gameUser.getUuid().equals(this.uuid)){
                return true;
            }
        }
        return false;
    }

    /**
     * 获取用户昵称
     * @return 用户昵称
     */
    @Override
    public String getNickName() {
        String nickName;
        synchronized (this){
            nickName = this.nickName;
        }
        return nickName;
    }

    /**
     * 获取用户房间
     * @return 用户房间
     */
    @Override
    public GameRoom getGameRoom() {
        GameRoom gameRoom;
        userRwlock.readLock().lock();
        try{
            gameRoom = this.gameRoom;
        }finally {
            userRwlock.readLock().unlock();
        }
        return gameRoom;
    }

    /**
     *
     * @return 用户uuid
     */
    @Override
    public String getUuid() {
        String uuid;
        userRwlock.readLock().lock();
        try{
            uuid = this.uuid;
        }finally {
            userRwlock.readLock().unlock();
        }
        return uuid;
    }

    /**
     *
     * @param gameRoom 游戏房间
     */
    @Override
    public void createRoom(GameRoom gameRoom) throws CreateRoomException {
        userRwlock.writeLock().lock();
        try{
            if (this.gameRoom != null) {
                throw new CreateRoomException();
            }
            this.gameRoom = gameRoom;
        }finally {
            userRwlock.writeLock().unlock();
        }
    }

    @Override
    public void joinRoom(GameRoom gameRoom) {
        userRwlock.writeLock().lock();
        try{
            if(this.gameRoom == null){
                this.gameRoom = gameRoom;
            }
        }finally {
            userRwlock.writeLock().unlock();
        }
    }

    /**
     *
     * 退出游戏房间
     */
    @Override
    public void cancelRoom(int type) {
        userRwlock.writeLock().lock();
        try{
            if(gameRoom == null){
                throw new NoRoomException();
            }
            if(type == ModelConstant.USER_CANCEL_ROOM){
                gameRoom.removeGameUser(this);
            }else{
                sendMessageToUser("用户" + uuid + "的房间已经解散");
            }
            this.gameRole = null;
            this.gameRoom = null;
        } catch (NoRoomException e) {
            e.printStackTrace();
        } finally {
            userRwlock.writeLock().unlock();
        }
    }

    /**
     * 销毁游戏房间
     */
    @Override
    public void distoryRoom() {
        userRwlock.writeLock().lock();
        try{
            if(gameRoom == null){
                throw new NoRoomException();
            }
            gameRoom.destroyRoom(this);
            this.gameRole = null;
            this.gameRoom = null;
        } catch (NoRoomException e) {
            e.printStackTrace();
        } finally {
            userRwlock.writeLock().unlock();
        }
    }

    @Override
    public void sendMessageToUser(String str) {
        try {
            if(ctx == null){
                throw new ChannelException();
            }
            if (ctx.isRemoved()) {
                throw new ChannelException();
            }
            ctx.writeAndFlush(str + "\r\n");
        } catch (ChannelException e) {
            e.printStackTrace();
        }
    }

    /**
     * 准备
     */
    @Override
    public void prepare() {
        userRwlock.readLock().lock();
        try{
            if (gameRoom == null) {
                throw new NoRoomException();
            }
            GameUser host = gameRoom.getHost();
            if(this.equals(host)){

            }
            this.playStatus = ModelConstant.USER_READY;
            gameRoom.broadcastToAllUser("用户" + this.uuid + "已经准备",uuid);
        } catch (NoRoomException e) {
            e.printStackTrace();
        } finally {
            userRwlock.readLock().unlock();
        }
    }
}
